package cn.com.surker.production.service.impl;

import cn.com.surker.common.MessageCenterException;
import cn.com.surker.enums.production.CountBillTypeEnum;
import cn.com.surker.enums.production.ProductionContractTypeEnum;
import cn.com.surker.enums.production.car.CarModelTypeEnum;
import cn.com.surker.enums.production.car.OverLimitEnum;
import cn.com.surker.enums.production.car.TransportTypeEnum;
import cn.com.surker.enums.production.indent.RoadTypeEnum;
import cn.com.surker.enums.production.invoice.TranTypeEnum;
import cn.com.surker.enums.system.BillPriceTypeEnum;
import cn.com.surker.excel.ExcelReportUtils;
import cn.com.surker.oa.dao.OaProductionContractDao;
import cn.com.surker.oa.entity.OaProductionContract;
import cn.com.surker.production.dao.ProductionOilPriceDao;
import cn.com.surker.production.dao.ProductionTransportBillDao;
import cn.com.surker.production.entity.ProductionOilPrice;
import cn.com.surker.production.entity.ProductionTransportBill;
import cn.com.surker.production.service.TranBillService;
import cn.com.surker.production.vo.TranBillVo;
import cn.com.surker.spring.RestResultDto;
import cn.com.surker.system.dao.SysOriginDao;
import cn.com.surker.system.entity.SysOrigin;
import cn.com.surker.util.DateUtil;
import cn.com.surker.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * @Author lucky
 * @create 2025年06月09 9:39
 * @desc
 */
@Service
public class TranBillServiceImpl implements TranBillService {

    @Resource
    private ProductionTransportBillDao transportBillDao;
    @Resource
    private OaProductionContractDao productionContractDao;
    @Resource
    private ProductionOilPriceDao oilPriceDao;
    @Resource
    private SysOriginDao originDao;

    /**
     * 分页查询运输结算
     * @param billVo
     * @param offset
     * @param limit
     * @return
     */
    public IPage findByPage(TranBillVo billVo, Integer offset, Integer limit) {
        PageHelper.offsetPage(offset, limit);
        QueryWrapper<ProductionTransportBill> billQuery = new QueryWrapper<>();
        if (StringUtils.isNull(billVo.getStatus()))
            billVo.setStatus(0);
        billQuery.eq("status", billVo.getStatus());
        if (!StringUtils.isNull(billVo.getOrgId()))
            billQuery.eq("org_id", billVo.getOrgId());
        if (!StringUtils.isNull(billVo.getSupplierId()))
            billQuery.eq("supplier_id", billVo.getSupplierId());
        if (!StringUtils.isNull(billVo.getTranType()))
            billQuery.eq("tran_type", billVo.getTranType());
        if (!StringUtils.isNull(billVo.getCountType()))
            billQuery.eq("count_type", billVo.getCountType());
        if (!StringUtils.isNull(billVo.getCarModelType()))
            billQuery.eq("car_model_type", billVo.getCarModelType());
        if (!StringUtils.isNull(billVo.getIsBill()))
            billQuery.eq("is_bill", billVo.getIsBill());
        if (!StringUtils.isNull(billVo.getPriceType()))
            billQuery.eq("price_type", billVo.getPriceType());
        if (!StringUtils.isNull(billVo.getStartTime()))
            billQuery.ge("start_time", billVo.getStartTime());
        if (!StringUtils.isNull(billVo.getEndTime()))
            billQuery.lt("start_time", billVo.getEndTime());
        if (!StringUtils.isNull(billVo.getSearchVal()))
            billQuery.and(orderWrapper -> orderWrapper.like("supplier", billVo.getSearchVal()).or()
                    .like("con_name", billVo.getSearchVal()).or().like("remark", billVo.getSearchVal()));
        billQuery.orderByDesc("today");
        billQuery.orderByAsc("supplier_id", "con_id", "tran_type", "car_model_type");
        IPage iPage = transportBillDao.selectPage(new Page<>((offset + limit) /limit, limit), billQuery);
        /**分页插件**/
        if (!StringUtils.isNull(iPage.getRecords())) {
            PageInfo pageInfo = new PageInfo(iPage.getRecords());
            if (!StringUtils.isNull(pageInfo.getTotal()))
                iPage.setTotal(pageInfo.getTotal());
        }
        return iPage;
    }

    public List<ProductionTransportBill> findBillList(TranBillVo billVo) {
        QueryWrapper<ProductionTransportBill> billQuery = new QueryWrapper<>();
        if (StringUtils.isNull(billVo.getStatus()))
            billVo.setStatus(0);
        billQuery.eq("status", billVo.getStatus());
        if (!StringUtils.isNull(billVo.getOrgId()))
            billQuery.eq("org_id", billVo.getOrgId());
        if (!StringUtils.isNull(billVo.getSupplierId()))
            billQuery.eq("supplier_id", billVo.getSupplierId());
        if (!StringUtils.isNull(billVo.getTranType()))
            billQuery.eq("tran_type", billVo.getTranType());
        if (!StringUtils.isNull(billVo.getCarModelType()))
            billQuery.eq("car_model_type", billVo.getCarModelType());
        if (!StringUtils.isNull(billVo.getIsBill()))
            billQuery.eq("is_bill", billVo.getIsBill());
        if (!StringUtils.isNull(billVo.getPriceType()))
            billQuery.eq("price_type", billVo.getPriceType());
        if (!StringUtils.isNull(billVo.getStartTime()))
            billQuery.ge("start_time", billVo.getStartTime());
        if (!StringUtils.isNull(billVo.getEndTime()))
            billQuery.lt("start_time", billVo.getEndTime());
        if (!StringUtils.isNull(billVo.getSearchVal()))
            billQuery.and(orderWrapper -> orderWrapper.like("supplier", billVo.getSearchVal()).or()
                    .like("con_name", billVo.getSearchVal()).or().like("remark", billVo.getSearchVal()).or()
                    .like("remark", billVo.getSearchVal()).or().like("remark", billVo.getSearchVal()));
        billQuery.orderByDesc("today");
        billQuery.orderByAsc("supplier_id", "con_id", "tran_type", "car_model_type");
        List<ProductionTransportBill> billList = transportBillDao.selectList(billQuery);
        if (billList == null || billList.size() == 0)
            return null;
        return billList;
    }

    public List<ProductionTransportBill> findBillData(TranBillVo billVo) {

        return null;
    }

    /**
     * 保存结算数据
     * @param bill
     * @return
     */
    public RestResultDto saveBill(ProductionTransportBill bill) {
        if (bill == null)
            throw new MessageCenterException("新增参数错误");
        if (StringUtils.isAllParamNull(bill.getOrgId(), bill.getOrgName()))
            throw new MessageCenterException("请选择公司");
        if (StringUtils.isAllParamNull(bill.getSupplierId(), bill.getSupplier()))
            throw new MessageCenterException("请选择供应商信息");
        if (StringUtils.isNull(bill.getCarModelType()))
            throw new MessageCenterException("请选择车辆类型");
        if (StringUtils.isNull(bill.getTranType()))
            throw new MessageCenterException("请选择运输类型");
        if (StringUtils.isNull(bill.getPriceType()))
            throw new MessageCenterException("请选择价格类型");
        if (StringUtils.isNull(bill.getIsBill()))
            throw new MessageCenterException("请选择结算类型");
        if (StringUtils.isNull(bill.getToday()))
            throw new MessageCenterException("请选择结算月份");
        if (StringUtils.isAllParamNull(bill.getStartTime(), bill.getEndTime()))
            throw new MessageCenterException("请选择结算时间周期");
        if (StringUtils.isNull(bill.getStere()))
            throw new MessageCenterException("请输入结算方量");
        if (StringUtils.isNull(bill.getPrice()))
            throw new MessageCenterException("请输入结算单价");
        if (StringUtils.isNull(bill.getTranNo()))
            throw new MessageCenterException("请输入结算车次");
        if (StringUtils.isNull(bill.getRoadType()))
            bill.setRoadType(RoadTypeEnum.NORMAL.getCode());
        if (StringUtils.isNull(bill.getOverLimit()))
            bill.setOverLimit(OverLimitEnum.BCX.getCode());
        if (StringUtils.isNull(bill.getOilPrice()))
            bill.setOilPrice(0.0);
        QueryWrapper<OaProductionContract> productionQuery = new QueryWrapper<>();
        productionQuery.eq("status", 0);
        productionQuery.eq("type", ProductionContractTypeEnum.TRANSPORT.getCode());
        productionQuery.eq("sid", bill.getSupplierId());
        productionQuery.orderByDesc("id");
        List<OaProductionContract> productionList = productionContractDao.selectList(productionQuery);
        if (productionList == null || productionList.size() == 0)
            throw new MessageCenterException("未获取到该供应商的生产运输合同");

        OaProductionContract contract = productionList.get(0);
        Double totalPrice = 0.0;
        if (bill.getPrice().doubleValue() != 0 && bill.getStere().doubleValue() != 0)
            totalPrice = StringUtils.formatDouble((bill.getPrice() + bill.getOilPrice()) * bill.getStere(), 2);
        ProductionTransportBill exBill =  transportBillDao.findExistBill(bill.getOrgId(), bill.getToday(), bill.getConId(), bill.getSupplierId(),
                bill.getTranType(), bill.getCountType(), bill.getCarModelType(), bill.getRoadType(), bill.getOverLimit(),
                bill.getPrice(), bill.getOilPrice());
        if (exBill != null) {
            exBill.setPrice(bill.getPrice());
            exBill.setOilPrice(bill.getOilPrice());
            exBill.setBillMoney(totalPrice);
            exBill.setUpdateTime(new Date());
            exBill.setUpdator(bill.getCreator());
            Integer code = transportBillDao.updateById(bill);
            return RestResultDto.success("更新成功");
        }
        bill.setBillMoney(totalPrice);
        bill.setStatus(0);
        bill.setIsAuto(1);
        bill.setCreateTime(new Date());
        bill.setTranConId(contract.getId());
        bill.setIsFinance(0);
        bill.setIsProduction(0);

        Integer code = transportBillDao.insert(bill);
        if (code > 0)
            return RestResultDto.success("保存成功");
        throw new MessageCenterException("保存失败");
    }

    /**
     * 修改结算数据
     * @param bill
     * @return
     */
    public RestResultDto updateBill(ProductionTransportBill bill) {
        if (bill == null || StringUtils.isNull(bill.getId()))
            throw new MessageCenterException("更新参数错误");
        ProductionTransportBill transportBill = transportBillDao.selectById(bill.getId());
        if (transportBill == null || transportBill.getStatus() == 1)
            throw new MessageCenterException("更新参数错误");
        bill.setUpdateTime(new Date());
        Integer code = transportBillDao.updateById(bill);
        if (code > 0)
            return RestResultDto.success("更新成功");
        throw new MessageCenterException("更新失败");
    }

    /**
     * 修改结算数据状态
     * @return
     */
    public RestResultDto updateStatus(Long id, Integer status, String creator) {
        if (StringUtils.isAllParamNull(id, status))
            throw new MessageCenterException("作废参数错误");
        ProductionTransportBill bill = transportBillDao.selectById(id);
        if (bill == null)
            throw new MessageCenterException("结算记录不存在");
        bill.setUpdator(creator);
        bill.setUpdateTime(new Date());
        bill.setStatus(status);
        Integer code = transportBillDao.updateById(bill);
        if (code > 0)
            return RestResultDto.success("作废成功");
        throw new MessageCenterException("作废失败");
    }

    /**
     * 修改结算数据状态
     * @return
     */
    public RestResultDto updateStatusV1(String today, Long orgId, Long conId, Long supplierId, Integer status, String creator) {
        if (StringUtils.isAllParamNull(today, orgId, supplierId, status))
            throw new MessageCenterException("作废参数错误");
        UpdateWrapper<ProductionTransportBill> uw = new UpdateWrapper<>();
        Date nowDate = new Date();
        uw.set("status", status);
        uw.set("update_time", DateUtil.convertString(nowDate));
        uw.set("updator", creator);
        uw.eq("org_id", orgId);
        uw.eq("supplier_id", supplierId);
        uw.eq("today", today);
        if (StringUtils.isNull(conId))
            uw.eq("con_id", conId);

        Integer code = transportBillDao.update(new ProductionTransportBill(), uw);
        if (code > 0)
            return RestResultDto.success("作废成功~！");
        throw new MessageCenterException("作废异常");
    }

    /**
     * 修改导出状态
     * @return
     */
    public RestResultDto updateExport(String today, Long orgId, Long supplierId, Integer isExport, String creator) {
        if (StringUtils.isAllParamNull(today, orgId, supplierId, isExport))
            throw new MessageCenterException("更新参数错误");
        UpdateWrapper<ProductionTransportBill> uw = new UpdateWrapper<>();
        Date nowDate = new Date();
        uw.set("is_export", isExport);
        uw.set("update_time", DateUtil.convertString(nowDate));
        uw.set("updator", creator);
        uw.eq("org_id", orgId);
        uw.eq("supplier_id", supplierId);
        uw.eq("is_export", 0);
        uw.eq("today", today);
        Integer code = transportBillDao.update(new ProductionTransportBill(), uw);
        if (code > 0)
            return RestResultDto.success("更新成功~！");
        throw new MessageCenterException("更新异常");
    }

    /**
     * 修改油价结算
     * @return
     */
    public RestResultDto updateOil(String today, Long orgId, Long supplierId, String creator) {
        if (StringUtils.isAllParamNull(today, orgId))
            throw new MessageCenterException("更新参数错误");
        QueryWrapper<ProductionOilPrice> oilQuery = new QueryWrapper<>();
        oilQuery.eq("status", 0);
        oilQuery.eq("today", today);
        oilQuery.eq("org_id", orgId);
        if (!StringUtils.isNull(supplierId))
            oilQuery.eq("supplier_id", supplierId);
        List<ProductionOilPrice> oilPriceList = oilPriceDao.selectList(oilQuery);
        if (oilPriceList == null || oilPriceList.size() == 0)
            throw new MessageCenterException("未获取到" + today + "结算油价信息");

        Map<Long, Double> oilMap = new HashMap<>();
        if (oilPriceList != null && oilPriceList.size() > 0) {//油价附件价
            for (ProductionOilPrice oilPrice : oilPriceList) {
                Double oilPrice_ = StringUtils.convertDouble(oilPrice.getAdjustPrice());
                Long supplierId_ = oilPrice.getSupplierId();
                oilMap.put(supplierId_, oilPrice_);
            }
        }
        QueryWrapper<ProductionTransportBill> billQuery = new QueryWrapper<>();
        billQuery.eq("status", 0);
        billQuery.eq("org_id", orgId);
        billQuery.eq("today", today);
        if (!StringUtils.isNull(supplierId))
            billQuery.eq("supplier_id", supplierId);
        List<ProductionTransportBill> billList = transportBillDao.selectList(billQuery);
        if (billList == null || billList.size() == 0)
            throw new MessageCenterException("未获取到" + today + "运输结算信息");
        Date nowDate = new Date();
        for (ProductionTransportBill bill : billList) {
            Long tempSupplierId = bill.getSupplierId();
            Double oilPrice = 0.0;
            if (oilMap.containsKey(tempSupplierId)) {
                oilPrice = StringUtils.convertDouble(oilMap.get(tempSupplierId));
                if (oilPrice.doubleValue() == 0)
                    continue;
                Double price = StringUtils.formatDouble(bill.getPrice() + oilPrice, 2);
                Double totalPrice = StringUtils.formatDouble(StringUtils.convertDouble(bill.getBillStere()) * price, 2);
                bill.setOilPrice(oilPrice);
                bill.setBillMoney(totalPrice);
                bill.setUpdateTime(nowDate);
                transportBillDao.updateById(bill);
            }
        }
        return RestResultDto.success("同步完成");
    }
    /**
     * 查询是否审核
     * @param orgId
     * @param today
     * @return
     */
    public Integer todayExamine(Long orgId, String today) {
        if (StringUtils.isAllParamNull(orgId, today))
            throw new MessageCenterException("查询审核记录参数错误");
        Integer total = transportBillDao.findExamineTotal(orgId, today);
        return total;
    }

    /**
     * 审核购进明细报表
     * @param orgId
     * @param today 时间点
     * @param creator
     * @param type 0 材料统计 1 财务
     * @return
     */
    public RestResultDto examineBill(Long orgId, String today, String creator, Integer type) {
        if (StringUtils.isAllParamNull(orgId, today, type))
            throw new MessageCenterException("审核泵送结算表参数错误");

        Date nowDate = new Date();
        String nowTime = DateUtil.convertString(nowDate);

        Integer code = -1;
        if (type == 0) {
            QueryWrapper<ProductionTransportBill> query = new QueryWrapper<>();
            query.eq("status",0);
            query.eq("org_id", orgId);
            query.eq("today", today);
            query.eq("is_production", 0);
            Integer total = transportBillDao.selectCount(query);
            if (total < 1)
                throw new MessageCenterException("没有审核的数据");
            UpdateWrapper<ProductionTransportBill> uw = new UpdateWrapper<>();
            uw.set("is_production", 1);
            uw.set("updator", creator);
            uw.set("update_time", DateUtil.convertString(nowDate));
            uw.eq("org_id", orgId);
            uw.eq("today", today);
            uw.eq("is_production", 0);
            uw.eq("is_finance", 0);
            transportBillDao.update(new ProductionTransportBill(), uw);
            return RestResultDto.success("审核成功");
        } else if (type == 1) {
            QueryWrapper<ProductionTransportBill> query = new QueryWrapper<>();
            query.eq("status",0);
            query.eq("org_id", orgId);
            query.eq("today", today);
            query.eq("is_production", 1);
            query.eq("is_finance", 0);
            Integer total = transportBillDao.selectCount(query);
            if (total < 1)
                throw new MessageCenterException("没有审核的数据");
            UpdateWrapper<ProductionTransportBill> uw = new UpdateWrapper<>();
            uw.set("is_finance", 1);
            uw.set("updator", creator);
            uw.set("update_time", DateUtil.convertString(nowDate));
            uw.eq("org_id", orgId);
            uw.eq("today", today);
            uw.eq("is_production", 1);
            uw.eq("is_finance", 0);
            transportBillDao.update(new ProductionTransportBill(), uw);
            return RestResultDto.success("审核成功");
        }
        throw new MessageCenterException("审核类型错误");
    }

    /**
     *
     * @return
     */
    public RestResultDto calcBill(Long orgId, Long conId, Long supplierId, Integer tranType, Integer countType,
                                  Integer roadType, Integer overLimit, Integer carModelType, String startTime,
                                  String endTime, String today, String creator) {
        if (StringUtils.isAllParamNull(orgId, today, startTime, endTime))
            throw new MessageCenterException("计算生产运输结算参数错误");
        String startDate = startTime.substring(0, 10);
        String endDate = endTime.substring(0, 10);
        List<TranBillVo>  billDayList = transportBillDao.findTranDayPrice(orgId, conId, supplierId, tranType,
                countType, roadType, overLimit, carModelType,
                startDate, endDate);
        if (billDayList == null || billDayList.size() == 0)
            throw new MessageCenterException("没有结算数据");

        SysOrigin origin = originDao.selectById(orgId);
        if (origin == null)
            throw new MessageCenterException("计算生产运输结算公司不存在");
        QueryWrapper<ProductionOilPrice> oilQuery = new QueryWrapper<>();
        oilQuery.eq("status", 0);
        oilQuery.eq("today", today);
        oilQuery.eq("org_id", orgId);
        if (!StringUtils.isNull(supplierId))
            oilQuery.eq("supplier_id", supplierId);
        List<ProductionOilPrice> oilPriceList = oilPriceDao.selectList(oilQuery);
        Map<Long, Double> oilMap = new HashMap<>();
        if (oilPriceList != null && oilPriceList.size() > 0) {//油价附件价
            for (ProductionOilPrice oilPrice : oilPriceList) {
                Double oilPrice_ = StringUtils.convertDouble(oilPrice.getAdjustPrice());
                Long supplierId_ = oilPrice.getSupplierId();
                oilMap.put(supplierId_, oilPrice_);
            }
        }
        List<ProductionTransportBill> billList = new ArrayList<>();
        String orgName = origin.getOriginName();
        Date nowDate = new Date();
        for (TranBillVo transportBill : billDayList) {
            Long tempTranContId = transportBill.getTranConId();
            Long tempSupplierId = transportBill.getSupplierId();
            Long tempConId = transportBill.getSupplierId();
            String conName = transportBill.getConName();
            Integer tempTranType = transportBill.getTranType();
            Integer tempCountType = transportBill.getCountType();
            Integer tempRoadType = transportBill.getRoadType();
            Integer tempOverLimit = transportBill.getOverLimit();
            Integer tempCarModelType = transportBill.getCarModelType();
            Integer tempPriceType = transportBill.getPriceType();
            Integer tranNo = transportBill.getTranNo();
            String tempSupplier = transportBill.getSupplier();
            String clientName = transportBill.getClientName();
            Double tempPrice = transportBill.getPrice();
            Double stere = transportBill.getStere();
            Double billStere = transportBill.getBillStere();
            Double distance = transportBill.getDistance();
            Double tempOilPrice = 0.0;
            if (oilMap != null && !StringUtils.isNull(oilMap.get(tempSupplierId)))
                tempOilPrice = StringUtils.convertDouble(oilMap.get(tempSupplierId));
            if (!StringUtils.isNull(clientName))
                conName = clientName + "[" + conName + "]";
            Double totalPrice = 0.0;
            if (!StringUtils.isNull(tempCountType)) {
                if (tempCountType.intValue() == CountBillTypeEnum.FL.getCode() || tempCountType.intValue() == CountBillTypeEnum.DW.getCode()) {
                    if (!StringUtils.isNull(billStere) && !StringUtils.isNull(tempPrice) && billStere != 0 && tempPrice != 0)
                        totalPrice = StringUtils.formatDouble(billStere * (tempPrice + tempOilPrice), 2);
                } else if (tempCountType.intValue() == CountBillTypeEnum.CC.getCode()) {
                    if (!StringUtils.isNull(billStere) && !StringUtils.isNull(tempPrice) && billStere != 0 && tempPrice != 0)
                        totalPrice = StringUtils.formatDouble(billStere * (tempPrice + tempOilPrice), 2);
                }
            }

            ProductionTransportBill existBill = transportBillDao.findExistBill(orgId, today, tempConId, tempSupplierId,
                    tempTranType, tempCountType, tempCarModelType, tempRoadType, tempOverLimit,
                    tempPrice, tempOilPrice);
            if (existBill != null) {
                Integer isAuto = existBill.getIsAuto();
                if (!StringUtils.isNull(isAuto) && isAuto == 1)//手动添加的不处理
                    continue;
                existBill.setStere(stere);
                existBill.setConName(conName);
                existBill.setConId(tempConId);
                existBill.setTranConId(tempTranContId);
                existBill.setSupplierId(tempSupplierId);
                existBill.setSupplier(tempSupplier);
                existBill.setOilPrice(tempOilPrice);
                existBill.setBillStere(billStere);
                existBill.setBillMoney(totalPrice);
                existBill.setUpdateTime(nowDate);
                existBill.setUpdator(creator);
                transportBillDao.updateById(existBill);
            } else {
                ProductionTransportBill tempBill = new ProductionTransportBill(orgId, orgName, today, tempConId,
                        conName, tempTranContId, tempSupplierId, tempSupplier, tempTranType, tempCountType,
                        tempCarModelType, tempRoadType, tempOverLimit, tempPriceType, 0, 0, stere, billStere,
                        tranNo, distance, tempOilPrice, tempPrice, totalPrice, 0, startTime, endTime, 0,
                        "", "", 0, "", "");
                tempBill.setStatus(0);
                tempBill.setCreateTime(nowDate);
                tempBill.setUpdateTime(nowDate);
                tempBill.setCreator(creator);
                tempBill.setRemark("系统同步计算结算数据");
                billList.add(tempBill);
            }
        }
        if (billList == null || billList.size() == 0)
            return RestResultDto.fail("没有结算数据");
        Integer code = transportBillDao.saveBatch(billList);
        if (code > 0)
            return RestResultDto.success("运输结算同步成功~！");
        throw new MessageCenterException("运输结算异常");
    }

    /**
     * 导出明细
     * @param sheetName
     * @param title
     * @param billList
     * @return
     */
    public XSSFWorkbook exportDetail(String sheetName, String title, List<ProductionTransportBill> billList) {
        if (billList == null || billList.size() == 0)
            throw new MessageCenterException("没有任何导出数据~！");
        Map<Integer, String> tranTypeMap = new HashMap<>();//运输类型
        Map<Integer, String> countTypeMap = new HashMap<>();//计算类型
        Map<Integer, String> carModelTypeMap = new HashMap<>();//车辆类型
        Map<Integer, String> roadTypeMap = new HashMap<>();//道路类型
        Map<Integer, String> priceTypeMap = new HashMap<>();//费用类型
        for (int i = 0; i < TransportTypeEnum.values().length; i++) {
            tranTypeMap.put(TransportTypeEnum.values()[i].getCode(), TransportTypeEnum.values()[i].getDescription());
        }
        for (int i = 0; i < CountBillTypeEnum.values().length; i++) {
            countTypeMap.put(CountBillTypeEnum.values()[i].getCode(), CountBillTypeEnum.values()[i].getDescription());
        }
        for (int i = 0; i < CarModelTypeEnum.values().length; i++) {
            carModelTypeMap.put(CarModelTypeEnum.values()[i].getCode(), CarModelTypeEnum.values()[i].getDescription());
        }
        for (int i = 0; i < RoadTypeEnum.values().length; i++) {
            roadTypeMap.put(RoadTypeEnum.values()[i].getCode(), RoadTypeEnum.values()[i].getDescription());
        }
        for (int i = 0; i < BillPriceTypeEnum.values().length; i++) {
            priceTypeMap.put(BillPriceTypeEnum.values()[i].getCode(), BillPriceTypeEnum.values()[i].getDescription());
        }

        XSSFWorkbook hw = new XSSFWorkbook();
        List<Map<String, Object>> list = new ArrayList<>();
        for (int i = 0; i < billList.size(); i++) {
            ProductionTransportBill billVo = billList.get(i);
            String billType = "是";
            String isAuto = "自动";
            String isCheck = "已审核";
            String isFinance = "已审核";
            String tranType = "";
            String countType = "";
            String carModelType = "";
            String overLimit = "不经过超限";
            String roadType = "";
            String priceType = "";
            if (!StringUtils.isNull(billVo.getTranType()))
                tranType = StringUtils.convertString(tranTypeMap.get(billVo.getTranType()));
            if (!StringUtils.isNull(billVo.getCountType()))
                countType = StringUtils.convertString(countTypeMap.get(billVo.getCountType()));
            if (!StringUtils.isNull(billVo.getCarModelType()))
                carModelType = StringUtils.convertString(carModelTypeMap.get(billVo.getCarModelType()));
            if (!StringUtils.isNull(billVo.getRoadType()))
                roadType = StringUtils.convertString(roadTypeMap.get(billVo.getRoadType()));
            if (!StringUtils.isNull(billVo.getPriceType()))
                priceType = StringUtils.convertString(priceTypeMap.get(billVo.getPriceType()));
            Map<String, Object> temp = new LinkedHashMap<>();
            if (!StringUtils.isNull(billVo.getOverLimit()) && billVo.getOverLimit() == 1)
                overLimit = "经过超限";
            if (!StringUtils.isNull(billVo.getIsBill()) && billVo.getPriceType() == 1)
                billType = "否";
            if (!StringUtils.isNull(billVo.getIsAuto()) && billVo.getIsAuto() == 1)
                isAuto = "手动";
            if (!StringUtils.isNull(billVo.getIsProduction()) && billVo.getIsProduction() == 0)
                isCheck = "未审核";
            if (!StringUtils.isNull(billVo.getIsFinance()) && billVo.getIsFinance() == 0)
                isFinance = "未审核";
            temp.put("orgName", billVo.getOrgName());
            temp.put("today", billVo.getToday());
            temp.put("conName", billVo.getConName());
            temp.put("supplier", billVo.getSupplier());
            temp.put("tranType", tranType);
            temp.put("countType", countType);
            temp.put("carModelType", carModelType);
            temp.put("roadType", roadType);
            temp.put("overLimit", overLimit);
            temp.put("priceType", priceType);
            temp.put("stere", StringUtils.formatDouble(billVo.getStere(), 2));
            temp.put("billStere", StringUtils.formatDouble(billVo.getBillStere(), 2));
            temp.put("price", StringUtils.formatDouble(billVo.getPrice(), 2));
            temp.put("oilPrice", StringUtils.formatDouble(billVo.getOilPrice(), 2));
            temp.put("billMoney", StringUtils.formatDouble(billVo.getBillMoney(), 2));
            temp.put("isBill", billType);
            temp.put("isAuto", isAuto);
            temp.put("startTime", billVo.getStartTime());
            temp.put("endTime", billVo.getEndTime());
            temp.put("isCheck", isCheck);
            temp.put("checker", billVo.getChecker());
            temp.put("checkTime", billVo.getCheckTime());
            temp.put("isFinance", isFinance);
            temp.put("finance", billVo.getFinance());
            temp.put("financeTime", billVo.getFinanceTime());
            temp.put("remark", billVo.getRemark());
            list.add(temp);
        }
        Object[] columns = {"公司","统计月份","工程名称","运输公司","运输类型","计算方式","车辆类型","道路类型","是否经超限",
                "费用类型","运输方量(m³)","结算方量(m³)","价格(元)","附加油价单价(元)",
                "结算金额(元)","是否结算","生成方式","结算开始时间","结算结束时间","统计审核",
                "审核人","审核时间","财务审核","审核人","审核时间","备注"};
        List<String> keyList = new ArrayList<>();
        keyList.add("stere");
        keyList.add("billStere");
        keyList.add("billMoney");
        hw = ExcelReportUtils.exportTotalReport(sheetName, title, columns,keyList, list, hw);
//        hw = ExcelMainMaterialUtils.materialPriceExamineWorkbook(sheetName, title, columns, list);
        return hw;
    }

    /**
     * 导出结算单
     * @return
     */
    public XSSFWorkbook exportBill(String sheetName, String title, Long orgId, Long supplierId, String startTime,
                            String endTime, List<ProductionTransportBill> billList, String creator) {

        return null;
    }
}
